#include "historyMananger.h"
#include "modelSoft.h"
#include <qmessagebox.h>
#include "BRepFilletAPI_MakeFillet.hxx"
#include "TopExp.hxx"
#include "BRep_Tool.hxx"
#include "BRepPrimAPI_MakePrism.hxx"
#include "BRepBuilderAPI_MakeFace.hxx"
#include "BRepPrimAPI_MakeRevol.hxx"
#include "BRepOffsetAPI_MakeThickSolid.hxx"
#include <boxWindow.h>
#include <QMouseEvent>
#include <coneWindow.h>
#include <cylinderWindow.h>
#include <torusWindow.h>
#include <sphereWindow.h>

historyMananger::historyMananger(modelSoft* modelSoft)
	: myModelSoft(modelSoft)
{
	historyTree = myModelSoft->ui->model;
	lastOperationType = -1;
	lastUndoFeature = nullptr;
	//connect历史树点击事件：实现某步操作的选择
	//connect(myModelSoft->ui->treeView, &QAbstractItemView::doubleClicked, this, &historyMananger::doubleClickedTree);
	connect(myModelSoft->ui->treeView, &QAbstractItemView::doubleClicked, this, &historyMananger::clickedTree);
	connect(myModelSoft->ui->treeView, &QAbstractItemView::clicked, this, &historyMananger::clickedTree);

	// 初始化定时器（略长于系统双击间隔）
	clickTimer = new QTimer(this);
	clickTimer->setSingleShot(true);
	clickTimer->setInterval(QApplication::doubleClickInterval() + 1);
	//std::cout << "clickTimer->setInterval() = " << clickTimer->interval() << std::endl; //延迟有点高了
	connect(clickTimer, &QTimer::timeout, this, &historyMananger::singleClick);
}

historyMananger::~historyMananger()
{
}

QString historyMananger::splitText(QString text, bool front) {
	QString result;
	if (front) {
		result = text.left(text.indexOf("-"));
	}
	else {
		result = text.right(text.length() - text.indexOf("-") - 1);
	}
	return result;
}

void historyMananger::undo()
{
	int row = historyTree->rowCount() - 1;
	if (row == -1) { //操作历史树为空
		return;
	}
	//获取操作历史树最后一行的item
    QStandardItem* operation = historyTree->item(row, 0);
	QString operationType = splitText(operation->text(), true);
	int operationId = splitText(operation->text(), false).toInt();
	if (operationType == "立方体" || operationType == "球体" || operationType == "圆柱体" || operationType == "圆锥" || operationType == "圆环体") {
		int shapeId = operationId;
		undoCreate(shapeId);
		lastOperationType = 0;
		historyTree->removeRow(row);
	}
	else if (operationType == "布尔运算") {
		int brepId = operationId;
		undoBrep(brepId);
		lastOperationType = 1;
		historyTree->removeRow(row);
	}
	else if (operationType == "倒圆角") {
		int filletId = operationId;
		undoFillet(filletId);
		lastOperationType = 2;
		historyTree->removeRow(row);
	}
	else if (operationType == "变换") {
		int transformId = operationId;
		undoTransform(transformId);
		lastOperationType = 3;
		historyTree->removeRow(row);
	}
	else if (operationType == "拉伸") {
		int stretchId = operationId;
		undoStretch(stretchId);
		lastOperationType = 4;
		historyTree->removeRow(row);
	}
	else if (operationType == "旋转体") {
		int revolId = operationId;
		undoRevol(revolId);
		lastOperationType = 5;
		historyTree->removeRow(row);
	}
	else if (operationType == "挖空") {
		int hollowId = operationId;
		undoHollow(hollowId);
		lastOperationType = 6;
		historyTree->removeRow(row);
	}
}

void historyMananger::undoByFeature(BaseFeature* feature)
{
	int operationType = feature->getFeatureType();
	if (operationType <= 5) {
		undoCreate(feature->getShapeId());
	}
	else if(operationType == 6){
		undoBrep(feature->getResultId());
	}
	else if (operationType == 7) {
		undoFillet(feature->getResultId());
	}
	else if (operationType == 8) {
		undoTransform(feature->getResultId());
	}
	else if (operationType == 9) {
		undoStretch(feature->getResultId());
	}
	else if (operationType == 10) {
		undoRevol(feature->getResultId());
	}
	else if (operationType == 11) {
		undoHollow(feature->getResultId());
	}
}

void historyMananger::undoCreate(int shapeId)
{
	auto iter = myModelSoft->m_Features.find(shapeId);
	if (iter == myModelSoft->m_Features.end()) {
		return;
	}
	//保存上一步撤销的特征，进行redo
	lastUndoFeature = iter->second;
	myModelSoft->RemovePipelineFromRendererById(shapeId);
}

void historyMananger::redo()
{
	if (lastOperationType == 0) {
		redoCreate(lastUndoFeature);
		lastOperationType = -1;
	}
	else if (lastOperationType == 1) {
		redoBrep((BrepFeature*)lastUndoFeature);
		lastOperationType = -1;
	}
	else if (lastOperationType == 2) {
		redoFillet((FilletFeature*)lastUndoFeature);
		lastOperationType = -1;
	}
	else if (lastOperationType == 3) {
		redoTransform((TransformFeature*)lastUndoFeature);
		lastOperationType = -1;
	}
	else if (lastOperationType == 4) {
		redoStretch((StretchFeature*)lastUndoFeature);
		lastOperationType = -1;
	}
	else if (lastOperationType == 5) {
		redoRevol((RevolFeature*)lastUndoFeature);
		lastOperationType = -1;
	}
	else if (lastOperationType == 6) {
		redoHollow((HollowFeature*)lastUndoFeature);
		lastOperationType = -1;
	}

}

Handle(QIVtkSelectionPipeline) historyMananger::redoCreate(BaseFeature* feature)
{
	int createType = feature->getFeatureType();
	switch (createType)
	{
	case 1:
	{
		Handle(QIVtkSelectionPipeline) cubePipeline = myModelSoft->makeBox((CubeFeature*)feature);
		if(!clicked){
			QStandardItem* item1 = new QStandardItem(QString("立方体-%1").arg(cubePipeline->GetShapeID()));
			int row = myModelSoft->ui->model->rowCount();
			item1->setEditable(false);
			myModelSoft->ui->model->setItem(row, 0, item1);
			QStandardItem* item2 = new QStandardItem(QString("隐藏"));
			item2->setCheckable(true);
			myModelSoft->ui->model->setItem(row, 1, item2);
		}
		return cubePipeline;
		break;
	}
	case 3:
	{
		Handle(QIVtkSelectionPipeline) spherePipeline = myModelSoft->makeSphere((SphereFeature*)feature);
		if (!clicked) {
			QStandardItem* item1 = new QStandardItem(QString("球体-%1").arg(spherePipeline->GetShapeID()));
			int row = myModelSoft->ui->model->rowCount();
			item1->setEditable(false);
			myModelSoft->ui->model->setItem(row, 0, item1);
			QStandardItem* item2 = new QStandardItem(QString("隐藏"));
			item2->setCheckable(true);
			myModelSoft->ui->model->setItem(row, 1, item2);
		}
		return spherePipeline;
		break;
	}
	case 4:
	{
		Handle(QIVtkSelectionPipeline) cylinderPipeline = myModelSoft->makeCylinder((CylinderFeature*)feature);
		if (!clicked) {
			QStandardItem* item1 = new QStandardItem(QString("圆柱体-%1").arg(cylinderPipeline->GetShapeID()));
			int row = myModelSoft->ui->model->rowCount();
			item1->setEditable(false);
			myModelSoft->ui->model->setItem(row, 0, item1);
			QStandardItem* item2 = new QStandardItem(QString("隐藏"));
			item2->setCheckable(true);
			myModelSoft->ui->model->setItem(row, 1, item2);
		}
		return cylinderPipeline;
		break;
	}
	case 2:
	{
		Handle(QIVtkSelectionPipeline) conePipeline = myModelSoft->makeCone((ConeFeature*)feature);
		if (!clicked) {
			QStandardItem* item1 = new QStandardItem(QString("圆锥-%1").arg(conePipeline->GetShapeID()));
			int row = myModelSoft->ui->model->rowCount();
			item1->setEditable(false);
			myModelSoft->ui->model->setItem(row, 0, item1);
			QStandardItem* item2 = new QStandardItem(QString("隐藏"));
			item2->setCheckable(true);
			myModelSoft->ui->model->setItem(row, 1, item2);
		}
		return conePipeline;
		break;
	}
	case 5:
	{
		Handle(QIVtkSelectionPipeline) torusPipeline = myModelSoft->makeTorus((TorusFeature*)feature);
		if (!clicked) {
			QStandardItem* item1 = new QStandardItem(QString("圆环体-%1").arg(torusPipeline->GetShapeID()));
			int row = myModelSoft->ui->model->rowCount();
			item1->setEditable(false);
			myModelSoft->ui->model->setItem(row, 0, item1);
			QStandardItem* item2 = new QStandardItem(QString("隐藏"));
			item2->setCheckable(true);
			myModelSoft->ui->model->setItem(row, 1, item2);
		}
		return torusPipeline;
		break;
	}
	default:
		break;
	}

	return nullptr;
}

void historyMananger::undoBrep(int brepId)
{
	auto iter = myModelSoft->m_Features.find(brepId);
	if (iter == myModelSoft->m_Features.end()) {
		return;
	}
	//保存撤销的特征，以防redo
	lastUndoFeature = iter->second;
	myModelSoft->RemovePipelineFromRendererById(lastUndoFeature->getResultId());
	lastUndoFeature->getTargetFeature()->DeleteOperation(lastUndoFeature);
	lastUndoFeature->getToolFeature()->DeleteOperation(lastUndoFeature);

	//重做目标体
	redoByFeature(lastUndoFeature->getTargetFeature());
	//lastUndoFeature->getTargetFeature()->DeleteOperation(lastUndoFeature);
	if(!clicked){
		int row1 = historyTree->rowCount() - 1;
		historyTree->removeRow(row1);
	}
	//if (lastUndoFeature->getTargetFeature()->getFeatureType() <= 5) {
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getTargetFeature());
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 6) {
	//	//重做布尔运算的目标体和工具体
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getTargetFeature()->getTargetFeature());
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getTargetFeature()->getToolFeature());
	//	redoBrep((BrepFeature*)lastUndoFeature->getTargetFeature());
	//	int row = historyTree->rowCount() - 1;
	//	historyTree->removeRow(row);
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 7) {//:fillet
	//	redoFillet((FilletFeature*)lastUndoFeature->getTargetFeature());
	//	int row = historyTree->rowCount() - 1;
	//	historyTree->removeRow(row);
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 8) {//: tranform
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 9) {//: stretch
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 10) {//: revol
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 11) {// : hollow
	//}

	//重做工具体
	redoByFeature(lastUndoFeature->getToolFeature());
	//lastUndoFeature->getToolFeature()->DeleteOperation(lastUndoFeature);
	if (!clicked) {
		int row2 = historyTree->rowCount() - 1;
		historyTree->removeRow(row2);
	}
	//if (lastUndoFeature->getToolFeature()->getFeatureType() <= 5) {
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getToolFeature());
	//}
	//else if (lastUndoFeature->getToolFeature()->getFeatureType() == 6) {
	//	//重做布尔运算的目标体和工具体
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getToolFeature()->getTargetFeature());
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getToolFeature()->getToolFeature());
	//	redoBrep((BrepFeature*)lastUndoFeature->getToolFeature());
	//	int row = historyTree->rowCount() - 1;
	//	historyTree->removeRow(row);
	//}
	//else if (lastUndoFeature->getToolFeature()->getFeatureType() == 7) {//:fillet
	//}
	//else if (lastUndoFeature->getToolFeature()->getFeatureType() == 8) {//: tranform
	//}
	//else if (lastUndoFeature->getToolFeature()->getFeatureType() == 9) {//: stretch
	//}
	//else if (lastUndoFeature->getToolFeature()->getFeatureType() == 10) {//: revol
	//}
	//else if (lastUndoFeature->getToolFeature()->getFeatureType() == 11) {// : hollow
	//}
	
}

Handle(QIVtkSelectionPipeline) historyMananger::redoBrep(BrepFeature* feature)
{
	//查找初始运算体Pipeline
	BaseFeature* targetFeature = feature->getTargetFeature();
	auto iter1 = myModelSoft->m_pipelineMap.find(targetFeature->getShapeId());
	Handle(QIVtkSelectionPipeline) targetPipeline;
	if (iter1 == myModelSoft->m_pipelineMap.end()) {
		targetPipeline = redoByFeature(targetFeature);
		int row1 = historyTree->rowCount() - 1;
		historyTree->removeRow(row1);
	}
	else {
		targetPipeline = iter1->second;
	}
	
	BaseFeature* toolFeature = feature->getToolFeature();
	auto iter2 = myModelSoft->m_pipelineMap.find(toolFeature->getShapeId());
	Handle(QIVtkSelectionPipeline) toolPipeline;
	if (iter2 == myModelSoft->m_pipelineMap.end()) {
		toolPipeline = redoByFeature(toolFeature);
	}
	else {
		toolPipeline = iter2->second;
	}
	TopoDS_Shape resultShape;
	//Brep运算
	myModelSoft->BrepOperation(resultShape, targetPipeline->getShape(), toolPipeline->getShape(), feature->getBrepType());
	Handle(QIVtkSelectionPipeline) resultPipeline = myModelSoft->CreatePipeline(resultShape, feature->getResultId(), true);
	//运算重新加入体素的操作list
	feature->AddOperation(feature);
	// 删除运算体
	myModelSoft->RemovePipelineFromRenderer(targetPipeline);
	myModelSoft->RemovePipelineFromRenderer(toolPipeline);
	feature->setResultId(resultPipeline->GetShapeID());
	//更新历史树
	if (!clicked) {
		QStandardItem* item1 = new QStandardItem(QString("布尔运算-%1").arg(feature->getBrepId()));
		int row = myModelSoft->ui->model->rowCount();
		item1->setEditable(false);
		myModelSoft->ui->model->setItem(row, 0, item1);
		QStandardItem* item2 = new QStandardItem(QString("隐藏"));
		item2->setCheckable(true);
		myModelSoft->ui->model->setItem(row, 1, item2);
		myModelSoft->myView->getRenderWindow()->Render();
	}
	
	return resultPipeline;
}

void historyMananger::undoFillet(int filletId)
{
	auto iter = myModelSoft->m_Features.find(filletId);
	if (iter == myModelSoft->m_Features.end()) {
		return;
	}
	//保存撤销的特征，以防redo
	lastUndoFeature = iter->second;

	myModelSoft->RemovePipelineFromRendererById(lastUndoFeature->getResultId());

	//重做目标体
	redoByFeature(lastUndoFeature->getTargetFeature());
	lastUndoFeature->getTargetFeature()->DeleteOperation(lastUndoFeature);
	if (!clicked) {
		int row = historyTree->rowCount() - 1;
		historyTree->removeRow(row);
	}
	//if (lastUndoFeature->getTargetFeature()->getFeatureType() <= 5) {
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getTargetFeature());
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 6) { //Brep
	//	//重做布尔运算的目标体和工具体
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getTargetFeature()->getTargetFeature());
	//	myModelSoft->CreatePipelineByFeature(lastUndoFeature->getTargetFeature()->getToolFeature());
	//	redoBrep((BrepFeature*)lastUndoFeature->getTargetFeature());
	//	int row = historyTree->rowCount() - 1;
	//	historyTree->removeRow(row);
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 7) {//:fillet
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 8) {//: tranform
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 9) {//: stretch
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 10 ) {//: revol
	//}
	//else if (lastUndoFeature->getTargetFeature()->getFeatureType() == 11) {// : hollow
	//}
}

Handle(QIVtkSelectionPipeline) historyMananger::redoFillet(FilletFeature* feature)
{
	BaseFeature* targetFeature = feature->getTargetFeature();
	auto iter1 = myModelSoft->m_pipelineMap.find(targetFeature->getShapeId());
	Handle(QIVtkSelectionPipeline) targetPipeline;
	if (iter1 == myModelSoft->m_pipelineMap.end()) {
		targetPipeline = redoByFeature(targetFeature);
		int row1 = historyTree->rowCount() - 1;
		historyTree->removeRow(row1);
	}
	else {
		targetPipeline = iter1->second;
	}
	BRepFilletAPI_MakeFillet MF(targetPipeline->getShape());
	TopTools_IndexedMapOfShape M;
	TopExp::MapShapes(targetPipeline->getShape(), TopAbs_EDGE, M);
	//int count = M.Extent();
	TopoDS_Shape subEdge = M.FindKey(feature->getSubEdgeIndex());
	MF.Add(feature->getRadius(), TopoDS::Edge(subEdge));
	Handle(QIVtkSelectionPipeline) pipeline = myModelSoft->CreatePipeline(MF.Shape(), feature->getFilletId(), true);
	//运算重新加入体素的操作list
	feature->AddOperation(feature);
	myModelSoft->RemovePipelineFromRenderer(targetPipeline);
	myModelSoft->myView->getRenderWindow()->Render();
	if(!clicked){
		QStandardItem* item1 = new QStandardItem(QString("倒圆角-%1").arg(feature->getFilletId()));
		int row = myModelSoft->ui->model->rowCount();
		item1->setEditable(false);
		myModelSoft->ui->model->setItem(row, 0, item1);
		QStandardItem* item2 = new QStandardItem(QString("隐藏"));
		item2->setCheckable(true);
		myModelSoft->ui->model->setItem(row, 1, item2);
	}

	return pipeline;
}

void historyMananger::undoTransform(int transformId)
{
	auto iter = myModelSoft->m_Features.find(transformId);
	if (iter == myModelSoft->m_Features.end()) {
		return;
	}
	//保存撤销的特征，以防redo
	lastUndoFeature = iter->second;

	myModelSoft->RemovePipelineFromRendererById(lastUndoFeature->getResultId());

	//重做目标体
	redoByFeature(lastUndoFeature->getTargetFeature());
	lastUndoFeature->getTargetFeature()->DeleteOperation(lastUndoFeature);
	if (!clicked) {
		int row = historyTree->rowCount() - 1;
		historyTree->removeRow(row);
	}
}

Handle(QIVtkSelectionPipeline) historyMananger::redoTransform(TransformFeature* feature)
{
	//创建变换
	gp_Trsf transform;
	gp_Trsf rotationTrsf;
	gp_Trsf vecTrsf;
	gp_Pnt rotateStart = gp_Pnt(0, 0, 0);
	gp_Pnt rotateEnd = gp_Pnt(0, 0, 0);
	int transformType = feature->getTransformType();
	//目标体
	BaseFeature* targetFeature = feature->getTargetFeature();
	auto iter1 = myModelSoft->m_pipelineMap.find(targetFeature->getShapeId());
	Handle(QIVtkSelectionPipeline) targetPipeline;
	if (iter1 == myModelSoft->m_pipelineMap.end()) {
		targetPipeline = redoByFeature(targetFeature);
		int row1 = historyTree->rowCount() - 1;
		historyTree->removeRow(row1);
	}
	else {
		targetPipeline = iter1->second;
	}

	//查找旋转轴
	if (feature->getSubEdgeIndex() != -1) {
		TopTools_IndexedMapOfShape M;
		TopExp::MapShapes(targetPipeline->getShape(), TopAbs_EDGE, M);
		//int count = M.Extent();
		const TopoDS_Edge& subEdge = TopoDS::Edge(M.FindKey(feature->getSubEdgeIndex()));
		const TopoDS_Vertex& firstVertex = TopExp::FirstVertex(subEdge);
		const TopoDS_Vertex& lastVertex = TopExp::LastVertex(subEdge);
		rotateStart = BRep_Tool::Pnt(firstVertex);
		rotateEnd = BRep_Tool::Pnt(lastVertex);

		// 判断旋转是否有效
		if (transformType ==0 || transformType == 2)
		{
			gp_Dir rotateDir((rotateEnd.X() - rotateStart.X()), (rotateEnd.Y() - rotateStart.Y()), (rotateEnd.Z() - rotateStart.Z()));
			gp_Ax1 rotationAxis(rotateStart, rotateDir);
			rotationTrsf.SetRotation(rotationAxis, feature->getAngel());
		}
	}
	
	// 判断平移是否有效
	if (transformType >= 1)
	{
		// 计算平移向量
		vecTrsf.SetTranslation(feature->getTranslationVec());
	}


	if (transformType == -1) {
		std::cout << "transform is invalid" << std::endl;
		return nullptr;
	}
	else if (transformType == 1) {
		transform = vecTrsf;
	}
	else if (transformType == 0) {
		transform = rotationTrsf;
	}
	else {
		transform = rotationTrsf * vecTrsf;
	}
	Handle(QIVtkSelectionPipeline) resultPipeline = myModelSoft->TransformActor(targetPipeline, transform, feature->getResultId());
	//运算重新加入体素的操作list
	feature->AddOperation(feature);
	if(!clicked){
		QStandardItem* item1 = new QStandardItem(QString("变换-%1").arg(feature->getTransformId()));
		int row = myModelSoft->ui->model->rowCount();
		item1->setEditable(false);
		myModelSoft->ui->model->setItem(row, 0, item1);
		QStandardItem* item2 = new QStandardItem(QString("隐藏"));
		item2->setCheckable(true);
		myModelSoft->ui->model->setItem(row, 1, item2);
	}

	return resultPipeline;
}

void historyMananger::undoStretch(int stretchId)
{
	auto iter = myModelSoft->m_Features.find(stretchId);
	if (iter == myModelSoft->m_Features.end()) {
		return;
	}
	//保存撤销的特征，以防redo
	lastUndoFeature = iter->second;

	myModelSoft->RemovePipelineFromRendererById(lastUndoFeature->getResultId());

	//重做目标体(Stretch生成新的pipeline，没有对原目标体修改，无需重做)
	if (!clicked) {
		int row = historyTree->rowCount() - 1;
		historyTree->removeRow(row);
	}
}

Handle(QIVtkSelectionPipeline) historyMananger::redoStretch(StretchFeature* feature)
{
	gp_Vec stretchDirection = feature->getStretchVec();
	int stretchType = feature->getStretchType();
	//查找目标体
	BaseFeature* targetFeature = feature->getTargetFeature();
	auto iter1 = myModelSoft->m_pipelineMap.find(targetFeature->getShapeId());
	Handle(QIVtkSelectionPipeline) targetPipeline;
	if (iter1 == myModelSoft->m_pipelineMap.end()) {
		targetPipeline = redoByFeature(targetFeature);
		int row1 = historyTree->rowCount() - 1;
		historyTree->removeRow(row1);
	}
	else {
		targetPipeline = iter1->second;
	}
	
	//查找选择的拉伸子对象
	TopoDS_Shape subShape;
	TopTools_IndexedMapOfShape M;
	if (feature->getSubShapeIndex() != -1) {

		if (stretchType == 0) {
			TopExp::MapShapes(targetPipeline->getShape(), TopAbs_VERTEX, M);
			subShape = M.FindKey(feature->getSubShapeIndex());
		}
		else if (stretchType == 1) {
			TopExp::MapShapes(targetPipeline->getShape(), TopAbs_EDGE, M);
			subShape = M.FindKey(feature->getSubShapeIndex());
			//int count = M.Extent();
		}
		else {
			TopExp::MapShapes(targetPipeline->getShape(), TopAbs_WIRE, M);
			TopoDS_Shape shape = M.FindKey(feature->getSubShapeIndex());
			subShape = BRepBuilderAPI_MakeFace(TopoDS::Wire(shape));
		}	
	}

	//redo
	Handle(QIVtkSelectionPipeline) resultPipeline;
	//判断拉伸方向是否有效
	if (!(IsNearlyZero(stretchDirection.X()) && IsNearlyZero(stretchDirection.Y()) && IsNearlyZero(stretchDirection.Z()))) {
		const TopoDS_Shape& newShape = BRepPrimAPI_MakePrism(subShape, stretchDirection);

		resultPipeline = myModelSoft->CreatePipeline(newShape, feature->getStretchId(), true);
		//selectPipeline->SetPipelineVisibility(false);
		myModelSoft->myView->getRenderWindow()->Render();
	}

	if (!clicked) {
		QStandardItem* item1 = new QStandardItem(QString("拉伸-%1").arg(feature->getStretchId()));
		int row = myModelSoft->ui->model->rowCount();
		item1->setEditable(false);
		myModelSoft->ui->model->setItem(row, 0, item1);
		QStandardItem* item2 = new QStandardItem(QString("隐藏"));
		item2->setCheckable(true);
		myModelSoft->ui->model->setItem(row, 1, item2);
	}
	
	return resultPipeline;
}

void historyMananger::undoRevol(int revolId)
{
	auto iter = myModelSoft->m_Features.find(revolId);
	if (iter == myModelSoft->m_Features.end()) {
		return;
	}
	//保存撤销的特征，以防redo
	lastUndoFeature = iter->second;

	myModelSoft->RemovePipelineFromRendererById(lastUndoFeature->getResultId());

	//重做目标体(Revol生成新的pipeline，没有对原目标体修改，无需重做)
	//redoByFeature(lastUndoFeature->getTargetFeature());
	if (!clicked) {
		int row = historyTree->rowCount() - 1;
		historyTree->removeRow(row);
	}
}

Handle(QIVtkSelectionPipeline) historyMananger::redoRevol(RevolFeature* feature)
{
	gp_Dir revolDir = feature->getRevolDir();
	gp_Pnt revolLocation = feature->getRevolLocation();
	int revolType = feature->getRevolType();
	//查找目标体
	BaseFeature* targetFeature = feature->getTargetFeature();
	auto iter1 = myModelSoft->m_pipelineMap.find(targetFeature->getShapeId());
	Handle(QIVtkSelectionPipeline) targetPipeline;
	if (iter1 == myModelSoft->m_pipelineMap.end()) {
		targetPipeline = redoByFeature(targetFeature);
		int row1 = historyTree->rowCount() - 1;
		historyTree->removeRow(row1);
	}
	else {
		targetPipeline = iter1->second;
	}

	//查找选择的拉伸子对象
	TopoDS_Shape subShape;
	TopTools_IndexedMapOfShape M;
	if (feature->getSubShapeIndex() != -1) {

		if (revolType == 0) {
			TopExp::MapShapes(targetPipeline->getShape(), TopAbs_VERTEX, M);
			subShape = M.FindKey(feature->getSubShapeIndex());
		}
		else if (revolType == 1) {
			TopExp::MapShapes(targetPipeline->getShape(), TopAbs_EDGE, M);
			subShape = M.FindKey(feature->getSubShapeIndex());
			//int count = M.Extent();
		}
		else {
			TopExp::MapShapes(targetPipeline->getShape(), TopAbs_WIRE, M);
			subShape = M.FindKey(feature->getSubShapeIndex());
		}
	}

	//redo
	Handle(QIVtkSelectionPipeline) resultPipeline;
	//判断旋转方向是否有效 以及是否被修改过
	if (!(IsNearlyZero(revolDir.X()) && IsNearlyZero(revolDir.Y()) && IsNearlyZero(revolDir.Z()))) {
		gp_Ax1 axis(revolLocation, revolDir);
		const TopoDS_Shape& newShape = BRepPrimAPI_MakeRevol(subShape, axis, false);
		resultPipeline = myModelSoft->CreatePipeline(newShape, feature->getRevolId(), true);
		myModelSoft->myView->getRenderWindow()->Render();
	}
	if (!clicked) {
		QStandardItem* item1 = new QStandardItem(QString("旋转体-%1").arg(feature->getRevolId()));
		int row = myModelSoft->ui->model->rowCount();
		item1->setEditable(false);
		myModelSoft->ui->model->setItem(row, 0, item1);
		QStandardItem* item2 = new QStandardItem(QString("隐藏"));
		item2->setCheckable(true);
		myModelSoft->ui->model->setItem(row, 1, item2);
	}

	return resultPipeline;
}

void historyMananger::undoHollow(int hollowId)
{
	auto iter = myModelSoft->m_Features.find(hollowId);
	if (iter == myModelSoft->m_Features.end()) {
		return;
	}
	//保存撤销的特征，以防redo
	lastUndoFeature = iter->second;

	myModelSoft->RemovePipelineFromRendererById(lastUndoFeature->getResultId());

	//重做目标体
	redoByFeature(lastUndoFeature->getTargetFeature());
	lastUndoFeature->getTargetFeature()->DeleteOperation(lastUndoFeature);
	if (!clicked) {
		int row = historyTree->rowCount() - 1;
		historyTree->removeRow(row);
	}
}

Handle(QIVtkSelectionPipeline) historyMananger::redoHollow(HollowFeature* feature)
{
	double D = feature->getHollowD();
	double tolerance = feature->getHollowTolerance();
	TopTools_ListOfShape facesToRemove;
	//查找目标体
	BaseFeature* targetFeature = feature->getTargetFeature();
	auto iter1 = myModelSoft->m_pipelineMap.find(targetFeature->getShapeId());
	Handle(QIVtkSelectionPipeline) targetPipeline;
	if (iter1 == myModelSoft->m_pipelineMap.end()) {
		targetPipeline = redoByFeature(targetFeature);
		int row1 = historyTree->rowCount() - 1;
		historyTree->removeRow(row1);
	}
	else {
		targetPipeline = iter1->second;
	}

	//查找选择的拉伸子对象
	TopoDS_Shape subShape;
	TopTools_IndexedMapOfShape M;
	TopExp::MapShapes(targetPipeline->getShape(), TopAbs_FACE, M);
	if (feature->getSubFaceIndexs().size() != 0) {
		for (int i = 0; i < feature->getSubFaceIndexs().size(); i++) {
			int subIndex = feature->getSubShapeIndexByIndex(i);
			subShape = M.FindKey(subIndex);
			facesToRemove.Append(TopoDS::Face(subShape));
		}
	}

	//redo
	Handle(QIVtkSelectionPipeline) resultPipeline;
	//判断厚度是否有效 以及是否被修改过
	if (!IsNearlyZero(D)) {
		BRepOffsetAPI_MakeThickSolid aSolidMaker;
		aSolidMaker.MakeThickSolidByJoin(targetPipeline->getShape(), facesToRemove, D, tolerance);
		const TopoDS_Shape newShape = aSolidMaker.Shape();

		resultPipeline = myModelSoft->CreatePipeline(newShape, feature->getHollowId(), true);
		//运算重新加入体素的操作list
		feature->AddOperation(feature);
		myModelSoft->RemovePipelineFromRenderer(targetPipeline);
		myModelSoft->myView->getRenderWindow()->Render();
	}
	if (!clicked) {
		QStandardItem* item1 = new QStandardItem(QString("挖空-%1").arg(feature->getHollowId()));
		int row = myModelSoft->ui->model->rowCount();
		item1->setEditable(false);
		myModelSoft->ui->model->setItem(row, 0, item1);
		QStandardItem* item2 = new QStandardItem(QString("隐藏"));
		item2->setCheckable(true);
		myModelSoft->ui->model->setItem(row, 1, item2);
	}
	
	return	resultPipeline;
}



Handle(QIVtkSelectionPipeline) historyMananger::redoByFeature(BaseFeature* feature)
{
	Handle(QIVtkSelectionPipeline) pipeline;
	int featureType = feature->getFeatureType();
	if (featureType <= 5) {//基础体素重做
		pipeline = redoCreate(feature);
	}
	else if (featureType == 6) {//Brep重做
		pipeline = redoBrep((BrepFeature*)feature);
	}
	else if (featureType == 7) {//Fillet重做
		pipeline = redoFillet((FilletFeature*)feature);
	}
	else if (featureType == 8) {//tranform重做
		pipeline = redoTransform((TransformFeature*)feature);
	}
	else if (featureType == 9) {//stretch重做
		pipeline = redoStretch((StretchFeature*)feature);
	}
	else if (featureType == 10 ) {//revol重做
		pipeline = redoRevol((RevolFeature*)feature);
	}
	else if (featureType == 11) {//hollow重做
		pipeline = redoHollow((HollowFeature*)feature);
	}

	return pipeline;
}

bool historyMananger::getHistorySelect()
{
	return this->historySelect;
}

void historyMananger::setHistorySelect(bool select)
{
    this->historySelect = select;
}
 
//双击修改特征
//对某模型操作后，Id改变，再点击初始创建操作选择会出错（重建了一个新的Pipeline)----->这种情况仍选择、类似表达式
void historyMananger::doubleClickedTree(const QModelIndex& index)
{
	
	clicked = true;
    QStandardItem* clickedItem = historyTree->itemFromIndex(index);
	int clickedItemRow = clickedItem->row();
	QStandardItem* operationExplain = historyTree->item(clickedItemRow, 0);
	int operationId = splitText(operationExplain->text(), false).toInt();
	QString operationType = splitText(operationExplain->text(), true);
	if (clickedItem->isCheckable()) {
		clicked = false;
		return;
	}
	auto iter = myModelSoft->m_Features.find(operationId);
	if (iter == myModelSoft->m_Features.end()) {
		clicked = false;
		return;
	}
	BaseFeature* feature = iter->second;
	//判断该模型是否被操作过，操作过则不选择
	std::list<BaseFeature *> list = feature->GetOperationList();
	historySelect = true;
	
	if (operationType == "立方体") {
		boxWindow* myBoxWindow = new boxWindow(myModelSoft, (CubeFeature*)feature);
		myBoxWindow->setWindowTitle("makeBox");
		myBoxWindow->setWindowModality(Qt::NonModal);
		myBoxWindow->setAttribute(Qt::WA_DeleteOnClose, true);
		myBoxWindow->setWindowFlags(myBoxWindow->windowFlags() | Qt::WindowStaysOnTopHint);
		myBoxWindow->show();
	}
	else if (operationType == "球体") {
		//唤起新窗口
		sphereWindow* mySphereWindow = new sphereWindow(myModelSoft,(SphereFeature*)feature);
		mySphereWindow->setWindowTitle("makeSphere");
		mySphereWindow->setWindowModality(Qt::NonModal);
		mySphereWindow->setAttribute(Qt::WA_DeleteOnClose, true);
		mySphereWindow->setWindowFlags(mySphereWindow->windowFlags() | Qt::WindowStaysOnTopHint);
		mySphereWindow->show();
	}
	else if (operationType == "圆柱体") {
		//唤起新窗口
		cylinderWindow* myCylinderWindow = new cylinderWindow(myModelSoft, (CylinderFeature*)feature);
		myCylinderWindow->setWindowTitle("makeCylinder");
		myCylinderWindow->setWindowModality(Qt::NonModal);
		myCylinderWindow->setAttribute(Qt::WA_DeleteOnClose, true);
		myCylinderWindow->setWindowFlags(myCylinderWindow->windowFlags() | Qt::WindowStaysOnTopHint);
		myCylinderWindow->show();
	}
	else if (operationType == "圆锥") {
		//唤起新窗口
		coneWindow* myConeWindow = new coneWindow(myModelSoft,(ConeFeature*)feature);
		myConeWindow->setWindowTitle("makeCone");
		myConeWindow->setWindowModality(Qt::NonModal);
		myConeWindow->setAttribute(Qt::WA_DeleteOnClose, true);
		myConeWindow->setWindowFlags(myConeWindow->windowFlags() | Qt::WindowStaysOnTopHint);
		myConeWindow->show();
	}
	else if (operationType == "圆环体") {
		//唤起新窗口
		torusWindow* myTorusWindow = new torusWindow(myModelSoft,(TorusFeature*)feature);
		myTorusWindow->setWindowTitle("makeTorus");
		myTorusWindow->setWindowModality(Qt::NonModal);
		myTorusWindow->setAttribute(Qt::WA_DeleteOnClose, true);
		myTorusWindow->setWindowFlags(myTorusWindow->windowFlags() | Qt::WindowStaysOnTopHint);
		myTorusWindow->show();
	}
	else if (clickedItem->text() == "布尔运算") {
		
	}
	else if (clickedItem->text() == "倒圆角") {
		
	}
	else if (clickedItem->text() == "变换") {
		
	}
	else if (clickedItem->text() == "拉伸") {
		
	}
	else if (clickedItem->text() == "旋转体") {
		
	}
	else if (clickedItem->text() == "挖空") {
		
	}
	clicked = false;
}

//单击高亮模型
void historyMananger::singleClick()
{
	
	clicked = true;
	QStandardItem* clickedItem = historyTree->itemFromIndex(clickedIndex);
	int clickedItemRow = clickedItem->row();
	QStandardItem* operationExplain = historyTree->item(clickedItemRow, 0);
	int operationId = splitText(operationExplain->text(), false).toInt();
	QString operationType = splitText(operationExplain->text(), true);
	//检查是否该item是否可勾选 已操作模型隐藏
	if (clickedItem->isCheckable()) {
		if (operationType == "布尔运算" || operationType == "拉伸" || operationType == "旋转体" || operationType == "挖空" || operationType == "倒圆角" || operationType == "变换") {
			auto iterFeature = myModelSoft->m_Features.find(operationId);
			if (iterFeature == myModelSoft->m_Features.end()) {
				clicked = false;
				return;
			}
			if (clickedItem->checkState() == Qt::Checked) {
				undoByFeature(iterFeature->second);
			}
			else {
				redoByFeature(iterFeature->second);
			}
		}
		else {
			auto iter = myModelSoft->m_pipelineMap.find(operationId);
			if (iter == myModelSoft->m_pipelineMap.end()) {
				clicked = false;
				return;
			}
			if (clickedItem->checkState() == Qt::Checked) {
				iter->second->SetPipelineVisibility(false);
				myModelSoft->myView->getRenderWindow()->Render();
			}
			else {
				iter->second->SetPipelineVisibility(true);
				myModelSoft->myView->getRenderWindow()->Render();
			}
		}
		clicked = false;
		return;
	}
	//单击高亮模型，已被操作的模型重建
	auto iter = myModelSoft->m_Features.find(operationId);
	if (iter == myModelSoft->m_Features.end()) {
		clicked = false;
		return;
	}
	BaseFeature* feature = iter->second;
	//判断该模型是否被操作过，操作过则不选择
	std::list<BaseFeature*> list = feature->GetOperationList();
	
	Handle(QIVtkSelectionPipeline) pipeline;
	auto iter1 = myModelSoft->m_pipelineMap.find(operationId);
    if (iter1 == myModelSoft->m_pipelineMap.end()) {
		//重建模型
		pipeline = redoByFeature(feature);
		pipeline->setTemporary(true);
		pipeline->Actor()->SetPickable(false);
		pipeline->Actor()->GetProperty()->DeepCopy(myModelSoft->myView->getInteractorStyle()->highlightProperty);
	}
	else {
        pipeline = iter1->second;
		if (pipeline->getTemporary()) {
			myModelSoft->RemovePipelineFromRenderer(pipeline);
		}
		else {
			if (pipeline->Actor()->GetProperty()->GetColor()[0] == 1) {
                pipeline->Actor()->GetProperty()->DeepCopy(myModelSoft->myView->getInteractorStyle()->baseProperty);
			}
			else {
				pipeline->Actor()->GetProperty()->DeepCopy(myModelSoft->myView->getInteractorStyle()->highlightProperty);
			}
		}
	}
	myModelSoft->myView->getRenderWindow()->Render();
	clicked = false;
}

void historyMananger::clickedTree(const QModelIndex& index)
{
	if (!clickTimer->isActive()) {
        clickTimer->start();
		clickedIndex = index;
	}
	else {
		clickTimer->stop();
		doubleClickedTree(clickedIndex);
	}
	
}



